package com.mky.mkcompany.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mky.mkcompany.controller.domain.DoPracticeReq;
import com.mky.mkcompany.controller.domain.DoTestSaveReq;
import com.mky.mkcompany.controller.domain.MyFalseQuestRes;
import com.mky.mkcompany.dao.*;
import com.mky.mkcompany.exception.WafException;
import com.mky.mkcompany.model.*;
import com.mky.mkcompany.model.view.UserFalseQuest;
import com.mky.mkcompany.model.view.UserFalseQuestCount;
import com.mky.mkcompany.tool.Arith;
import com.mky.mkcompany.tool.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.sql.*;
import java.util.*;
import java.util.Date;

/**
 * Created by Lenovo on 2017/9/1.
 */
@Service
public class UserDoTestService {
    private final Logger LOGGER = LoggerFactory.getLogger(getClass());
    @Autowired
    private PracticQuestDao practicQuestDao;
    @Autowired
    private UserDoPracticQuestDao userDoPracticQuestDao;
    @Autowired
    private UserCollectPracticQuestDao userCollectPracticQuestDao;
    @Autowired
    private SubjectCategoryDao subjectCategoryDao;
    @Autowired
    private SubjectChapterDao subjectChapterDao;
    @Autowired
    private UserTestDao userTestDao;
    @Autowired
    private TestInfoDao testInfoDao;
    @Autowired
    private TestQuestDao testQuestDao;
    @Autowired
    private UserDoTestDao userDoTestDao;
    @Autowired
    private UserDoTestQuestDao userDoTestQuestDao;
    @Autowired
    private UserDoTestSaveQuestDao userDoTestSaveQuestDao;

    public JSONObject getMyTestInfo(String examType,String userId,int page,int size){
        JSONObject res = new JSONObject();
        UserTest userTest=userTestDao.findByExamTypeAndUserId(examType,userId);
        long total=0;
        JSONArray array=new JSONArray();
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        if(userTest!=null){
            Pageable pageable = new PageRequest(page-1, size, sort);
            Pageable pageableDoTest = new PageRequest(0, 1, sort);
            Page<TestInfo>testInfoPage=testInfoDao.findTestInfoPage(examType,pageable);
            total=testInfoPage.getTotalElements();
            List<TestInfo>testInfos=testInfoPage.getContent();
            for(TestInfo testInfo:testInfos){
                JSONObject json=new JSONObject();
                 long questNum=testQuestDao.findCountByTestId(testInfo.getId());
                 long doTestNum=userDoTestDao.findCountByTestIdAndUserId(testInfo.getId(),userId);

                Page<UserDoTest> userDoTestPage=userDoTestDao.findObjsByTestIdAndUserId(testInfo.getId(),
                        userId,pageableDoTest);
                List<UserDoTest>userDoTests=userDoTestPage.getContent();
                double score=0;
                Long endTime=null;
                if(!ObjectUtils.isEmpty(userDoTests)){
                    UserDoTest userDoTest=userDoTests.get(0);
                   score=userDoTest.getScore();
                    endTime=userDoTest.getEndTime();
                }
                json.put("name",testInfo.getName());
                json.put("id",testInfo.getId());
                json.put("questNum",questNum);
                json.put("doTestNum",doTestNum);
                json.put("score",score);
                json.put("endTime",endTime);
                array.add(json);
            }
        }
        res.put("data",array);
        res.put("total",total);
        return res;
    }


    public JSONObject getDoTestHistoryInfo(String testId,String userId){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.DESC,"createTime");
        Pageable pageableDoTest = new PageRequest(0, 1000, sort);
        Page<UserDoTest> userDoTestPage=userDoTestDao.findObjsByTestIdAndUserId(testId,
                userId,pageableDoTest);
        List<UserDoTest>userDoTests=userDoTestPage.getContent();
        JSONArray array=new JSONArray();
        for(UserDoTest userDoTest:userDoTests){
            JSONObject json=new JSONObject();
            int time=DateUtil.computeDateDifferMinutes(userDoTest.getStartTime(),userDoTest.getEndTime());
            json.put("time",time);
            json.put("startTime",userDoTest.getStartTime());
            json.put("score",userDoTest.getScore());
            json.put("endTime",userDoTest.getEndTime());
            json.put("handPaperId",userDoTest.getHandPaperId());
            json.put("testId",userDoTest.getTestId());
            array.add(json);
        }
        res.put("data",array);
        return res;
    }

    public JSONObject getTestQuestInfo(String testId,String userId,int page,int size){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        Pageable pageable = new PageRequest(page-1, size, sort);
        Page<TestQuest> testQuestPage=testQuestDao.findObjsByTestId(testId,pageable);
        TestInfo testInfo=testInfoDao.findOne(testId);
        List<UserDoTestQuest>userDoTestQuests=userDoTestQuestDao.findByUserIdAndTestIdAndType(userId,testId,1);
        Map<String,UserDoTestQuest>userDoTestQuestMap=new HashMap<>();
        for(UserDoTestQuest userDoTestQuest:userDoTestQuests){
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(userDoTestQuest.getQuestId())
                    .append("-").append(userDoTestQuest.getTestId());
            userDoTestQuestMap.put(key.toString(),userDoTestQuest);
        }
        UserDoTestSaveQuest userDoTestSaveQuest=userDoTestSaveQuestDao.findByUserIdAndTestId(userId,testId);
        Integer minute=testInfo.getTestTime();
        Integer second=0;
        int noDoQuestNum=(int) testQuestPage.getTotalElements();
        if(userDoTestSaveQuest!=null){
            minute=userDoTestSaveQuest.getMinute();
            second=userDoTestSaveQuest.getSecond();
            noDoQuestNum=userDoTestSaveQuest.getNoDoQuestNum();
        }
        JSONArray array=new JSONArray();
        for(TestQuest testQuest:testQuestPage.getContent()){
            JSONObject json=(JSONObject) JSONObject.toJSON(testQuest);
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(testQuest.getId())
                    .append("-").append(testQuest.getTestId());
            UserDoTestQuest userDoTestQuest=userDoTestQuestMap.get(key.toString());
            String result=null;
            Integer isDoQuest=0;
            if(userDoTestQuest!=null){
                result=userDoTestQuest.getResult();
                isDoQuest=userDoTestQuest.getAnswerResult();
            }
            json.put("result",result);
            json.put("isDoQuest",isDoQuest);
            array.add(json);
        }
        res.put("data",array);
        res.put("name",testInfo.getName());
        res.put("total",testQuestPage.getTotalElements());
        res.put("time",testInfo.getTestTime());
        res.put("minute",minute);
        res.put("second",second);
        res.put("noDoQuestNum",noDoQuestNum);
        return res;
    }

    public void doTestQuestSave(DoTestSaveReq doTestSaveReq, String userId){
        Timestamp createTime= DateUtil.getNowTimestamp();
        Timestamp updateTime= DateUtil.getNowTimestamp();
        List<UserDoTestQuest>userDoTestQuests=userDoTestQuestDao.findByUserIdAndTestIdAndType(userId,doTestSaveReq.getTestId(),1);
        List<DoPracticeReq>doPracticeReqList=doTestSaveReq.getData();
        if(ObjectUtils.isEmpty(userDoTestQuests)){
            userDoTestQuests=new ArrayList<>();
            for(DoPracticeReq doPracticeReq:doPracticeReqList){
                String id= UUID.randomUUID().toString().replace("-","");
                UserDoTestQuest userDoTestQuest=new UserDoTestQuest();
                userDoTestQuest.setId(id);
                userDoTestQuest.setUserId(userId);
                userDoTestQuest.setQuestId(doPracticeReq.getQuestId());
                userDoTestQuest.setTestId(doTestSaveReq.getTestId());
                userDoTestQuest.setResult(doPracticeReq.getResult());
                userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
                userDoTestQuest.setType(1);
                userDoTestQuest.setCreateTime(createTime);
                userDoTestQuest.setUpdateTime(updateTime);
                userDoTestQuests.add(userDoTestQuest);
            }
        }else{
            Map<String,DoPracticeReq>doPracticeReqMap=new HashMap<>();
            for(DoPracticeReq doPracticeReq:doPracticeReqList){
                StringBuilder key=new StringBuilder();
                key.append(userId).append("-").append(doPracticeReq.getQuestId())
                        .append("-").append(doTestSaveReq.getTestId());
                doPracticeReqMap.put(key.toString(),doPracticeReq);
            }
            for(UserDoTestQuest userDoTestQuest:userDoTestQuests){
                StringBuilder key=new StringBuilder();
                key.append(userId).append("-").append(userDoTestQuest.getQuestId())
                        .append("-").append(doTestSaveReq.getTestId());
                DoPracticeReq doPracticeReq=doPracticeReqMap.get(key.toString());
                userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
                userDoTestQuest.setResult(doPracticeReq.getResult());
                userDoTestQuest.setUpdateTime(DateUtil.getNowTimestamp());
            }
        }
        UserDoTestSaveQuest userDoTestSaveQuest=userDoTestSaveQuestDao.findByUserIdAndTestId(userId,doTestSaveReq.getTestId());
        if(userDoTestSaveQuest==null){
           userDoTestSaveQuest=new UserDoTestSaveQuest();
            userDoTestSaveQuest.setId(UUID.randomUUID().toString().replace("-",""));
            userDoTestSaveQuest.setUserId(userId);
            userDoTestSaveQuest.setTestId(doTestSaveReq.getTestId());
            userDoTestSaveQuest.setMinute(doTestSaveReq.getMinute());
            userDoTestSaveQuest.setSecond(doTestSaveReq.getSecond());
            userDoTestSaveQuest.setStartTime(doTestSaveReq.getStartTime());
            userDoTestSaveQuest.setNoDoQuestNum(doTestSaveReq.getNoDoQuestNum());
            userDoTestSaveQuest.setCreateTime(DateUtil.getNowTimestamp());
            userDoTestSaveQuest.setUpdateTime(DateUtil.getNowTimestamp());

        }else{
            userDoTestSaveQuest.setMinute(doTestSaveReq.getMinute());
            userDoTestSaveQuest.setSecond(doTestSaveReq.getSecond());
            userDoTestSaveQuest.setNoDoQuestNum(doTestSaveReq.getNoDoQuestNum());
            userDoTestSaveQuest.setUpdateTime(DateUtil.getNowTimestamp());
        }
        userDoTestSaveQuestDao.save(userDoTestSaveQuest);
        userDoTestQuestDao.save(userDoTestQuests);
    }

    public void doTestQuestHand(DoTestSaveReq doTestSaveReq, String userId){
        Timestamp createTime= DateUtil.getNowTimestamp();
        Timestamp updateTime= DateUtil.getNowTimestamp();
        List<UserDoTestQuest>oldUserDoTestQuests=userDoTestQuestDao.findByUserIdAndTestIdAndType(userId,doTestSaveReq.getTestId(),1);
        userDoTestQuestDao.delete(oldUserDoTestQuests);
        UserDoTestSaveQuest userDoTestSaveQuest=userDoTestSaveQuestDao.findByUserIdAndTestId(userId,doTestSaveReq.getTestId());
        if(userDoTestSaveQuest!=null) {
            userDoTestSaveQuestDao.delete(userDoTestSaveQuest);
        }
        List<DoPracticeReq>doPracticeReqList=doTestSaveReq.getData();
        String handPaperId= UUID.randomUUID().toString().replace("-","");
        double score=0;
        String result="不及格";
        TestInfo testInfo=testInfoDao.findOne(doTestSaveReq.getTestId());
        Integer testScore=testInfo.getTestScore();
        int questNum=doPracticeReqList.size();
        Double questScore=Arith.div(testScore,questNum,2);
        Double passScore=testInfo.getPassScore();
        List<UserDoTestQuest>userDoTestQuests=new ArrayList<>();
        for(DoPracticeReq doPracticeReq:doPracticeReqList){
            if(doPracticeReq.getAnswerResult()==1){
                score+=questScore;
            }
            String id= UUID.randomUUID().toString().replace("-","");
            UserDoTestQuest userDoTestQuest=new UserDoTestQuest();
            userDoTestQuest.setId(id);
            userDoTestQuest.setUserId(userId);
            userDoTestQuest.setQuestId(doPracticeReq.getQuestId());
            userDoTestQuest.setTestId(doTestSaveReq.getTestId());
            userDoTestQuest.setResult(doPracticeReq.getResult());
            userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
            userDoTestQuest.setType(2);
            userDoTestQuest.setHandPaperId(handPaperId);
            userDoTestQuest.setCreateTime(createTime);
            userDoTestQuest.setUpdateTime(updateTime);
            userDoTestQuests.add(userDoTestQuest);
        }
        if(score>=passScore){
            result="及格";
        }
        UserDoTest userDoTest=new UserDoTest();
        userDoTest.setId(UUID.randomUUID().toString().replace("-",""));
        userDoTest.setHandPaperId(handPaperId);
        userDoTest.setUserId(userId);
        userDoTest.setTestId(doTestSaveReq.getTestId());
        userDoTest.setScore(score);
        userDoTest.setResult(result);
        userDoTest.setStartTime(doTestSaveReq.getStartTime());
        Date date=new Date();
        userDoTest.setEndTime(date.getTime());
        userDoTest.setCreateTime(DateUtil.getNowTimestamp());
        userDoTest.setUpdateTime(DateUtil.getNowTimestamp());
        userDoTestQuestDao.save(userDoTestQuests);
        userDoTestDao.save(userDoTest);
    }

    public JSONObject getHandPaperResult(String testId,String handPaperId,String userId){
        JSONObject res = new JSONObject();
        UserDoTest userDoTest=userDoTestDao.findByUserIdAndHandPaperId(userId,handPaperId);
        TestInfo testInfo=testInfoDao.findOne(testId);
        List<UserFalseQuest> userFalseQuests=userDoTestQuestDao.findFalseQuest(userId,handPaperId);
        Map<String,Integer>userFalseQuestMap=new HashMap<>();
        for(UserFalseQuest userFalseQuest:userFalseQuests){
            StringBuilder key=new StringBuilder(userFalseQuest.getSubjectName())
                    .append("-").append(userFalseQuest.getChapterName())
                    .append("-");
            if(!ObjectUtils.isEmpty(userFalseQuest.getTestCentre())){
                key.append(userFalseQuest.getTestCentre());
            }else{
                key.append("0");
            }
            Integer falseQuestNum=userFalseQuestMap.get(key.toString());
            if(falseQuestNum==null){
                falseQuestNum=1;
            }else{
                falseQuestNum++;
            }
            userFalseQuestMap.put(key.toString(),falseQuestNum);
        }
        JSONArray array=new JSONArray();
        for(Map.Entry<String, Integer> entries:userFalseQuestMap.entrySet()){
            JSONObject json = new JSONObject();
            String key=entries.getKey();
            String[] names=key.split("-");
            json.put("subjectName",names[0]);
            json.put("chapterName",names[1]);
            json.put("testCentre",names[2].equals("0")?"":names[2]);
            json.put("falseQuestNum",entries.getValue());
            array.add(json);
        }
        res.put("falseQuestChapterData",array);
        res.put("score",userDoTest.getScore());
        res.put("result",userDoTest.getResult());
        res.put("totalScore",testInfo.getTestScore());
        return res;
    }

    public JSONObject getHandTestResultInfo(String testId,String handPaperId,String userId,int page,int size){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        Pageable pageable = new PageRequest(page-1, size, sort);
        TestInfo testInfo=testInfoDao.findOne(testId);
        Page<TestQuest> testQuestPage=testQuestDao.findObjsByTestId(testId,pageable);
        UserDoTest userDoTest=userDoTestDao.findByUserIdAndHandPaperId(userId,handPaperId);
        List<UserDoTestQuest>userDoTestQuests=userDoTestQuestDao.findByUserIdAndHandPaperIdAndType(userId,handPaperId,2);
        Map<String,UserDoTestQuest>userDoTestQuestMap=new HashMap<>();
        for(UserDoTestQuest userDoTestQuest:userDoTestQuests){
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(userDoTestQuest.getQuestId())
                    .append("-").append(userDoTestQuest.getTestId());
            userDoTestQuestMap.put(key.toString(),userDoTestQuest);
        }
        JSONArray array=new JSONArray();
        for(TestQuest testQuest:testQuestPage.getContent()){
            JSONObject json=(JSONObject) JSONObject.toJSON(testQuest);
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(testQuest.getId())
                    .append("-").append(testQuest.getTestId());
            UserDoTestQuest userDoTestQuest=userDoTestQuestMap.get(key.toString());
            String result=null;
            Integer answerResult=0;
            if(userDoTestQuest!=null){
                result=userDoTestQuest.getResult();
                answerResult=userDoTestQuest.getAnswerResult();
            }
            json.put("result",result);
            json.put("answerResult",answerResult);
            array.add(json);
        }
        res.put("data",array);
        res.put("name",testInfo.getName());
        res.put("total",testQuestPage.getTotalElements());
        res.put("startTime",userDoTest.getStartTime());
        res.put("endTime",userDoTest.getEndTime());
        return res;
    }

    public JSONObject getMyFalseQuestListInfo(String examType,String subjectName
            ,String chapterName,String userId,int page,int size){
        JSONObject res = new JSONObject();
       List<UserFalseQuestCount>userFalseQuestCounts=userDoTestQuestDao.findFalseQuestByUserId(userId,examType);
        int total=userFalseQuestCounts.size();
        List<MyFalseQuestRes>myFalseQuestResList=new ArrayList<>();
        for(UserFalseQuestCount userFalseQuestCount:userFalseQuestCounts){
            TestQuest testQuest=testQuestDao.findOne(userFalseQuestCount.getQuestId());
            SubjectChapter subjectChapter=subjectChapterDao.findOne(testQuest.getChapterId());
            SubjectCategory subjectCategory=subjectCategoryDao.findOne(subjectChapter.getSubjectId());
            if(!"all".equals(subjectName) && !subjectName.equals(subjectCategory.getName())){
                continue;
            }
            if(!"all".equals(chapterName) && !chapterName.equals(subjectChapter.getName())){
                continue;
            }
             long answerFalsePersonNum=userDoTestQuestDao.findCountByQuestId(userFalseQuestCount.getQuestId()).size();
            MyFalseQuestRes myFalseQuestRes=new MyFalseQuestRes();
            myFalseQuestRes.setQuestId(userFalseQuestCount.getQuestId());
            myFalseQuestRes.setQuestName(testQuest.getTitle());
            myFalseQuestRes.setEndTime(DateUtil.formatDateTime(userFalseQuestCount.getEndTime(),"yyyy-MM-dd"));
            myFalseQuestRes.setChapterName(subjectChapter.getName());
            myFalseQuestRes.setSubjectName(subjectCategory.getName());
            myFalseQuestRes.setAnswerFalseNum((int)userFalseQuestCount.getNum());
            myFalseQuestRes.setAnswerFalsePersonNum((int)answerFalsePersonNum);
            myFalseQuestResList.add(myFalseQuestRes);
        }
        //实现分页
        int offset=(page-1)*size;
        int limit=page*size;
        if(limit>total){
            limit=total;
        }
        List<MyFalseQuestRes>data=new ArrayList<>();
        if(total>0 && offset<limit) {
            data = myFalseQuestResList.subList(offset, limit);
        }
         res.put("data",data);
        res.put("total",total);
        return res;
    }

    public JSONObject getMyFalseQuestInfo(String questId,String userId){
        JSONObject res = new JSONObject();
        TestQuest testQuest=testQuestDao.findOne(questId);
        SubjectChapter subjectChapter=subjectChapterDao.findOne(testQuest.getChapterId());
        SubjectCategory subjectCategory=subjectCategoryDao.findOne(subjectChapter.getSubjectId());
        TestInfo testInfo=testInfoDao.findOne(testQuest.getTestId());
        List<UserDoTestQuest>userDoTestQuests=userDoTestQuestDao.findByUserIdAndQuestIdAndAndAnswerResultAndType(
                userId,questId,2,2);
        int falseQuestNum=userDoTestQuests.size();
        res=(JSONObject)JSONObject.toJSON(testQuest);
        res.put("falseQuestNum",falseQuestNum);
        res.put("subjectName",subjectCategory.getName());
        res.put("chapterName",subjectChapter.getName());
        JSONArray array=new JSONArray();
        for(UserDoTestQuest userDoTestQuest:userDoTestQuests){
            JSONObject json=new JSONObject();
            json.put("testName",testInfo.getName());
            json.put("endTime",userDoTestQuest.getUpdateTime());
            json.put("result",userDoTestQuest.getResult());
            array.add(json);
        }
        res.put("listData",array);
        return res;
    }
}
